import { omit } from 'lodash-es';
import { FarrisDesignBaseNestedComponent } from '../base-component/nested-component';
import UIComponents from './components/components';
import Templates from './templates/templates';

export class Webform extends FarrisDesignBaseNestedComponent {

    _form;

    /** The type of this element. */
    type: string;

    /** Promise that executes when the form is ready and rendered. */
    formReady: Promise<any>;

    /**  Called when the formReady state of this form has been resolved.  */
    formReadyResolve: any;


    /** 表单是否已初始化，用于清除组件时进行销毁 */
    initialized: boolean;

    /** 不允许拖拽，暂时无用 */
    noDragDrop: any;

    getSchema(): any {
        const schema: any = omit(this._form, ['contents']);
        schema.contents = [];
        this.eachComponent((component) => schema.contents.push(component.getSchema()));
        return schema;
    }

    constructor(element: HTMLElement, options: any) {
        super(null, options);

        this.element = element;

        this.type = 'form';
        if (this.component) {
            this.component.id = '';
        }
        this.formReady = new Promise((resolve, reject) => {
            this.formReadyResolve = resolve;
            // this.formReadyReject = reject;
        });

        // this.init 是为了防止重复渲染增加的方法，原formio没有
        this.init();
    }


    /**
     * 表单渲染结束
     * @returns The promise to trigger when both form and submission have loaded.
     */
    getReady(): Promise<any> {
        return this.formReady.then(() => {
            // component渲染结束
            return super['ready'];
        });
    }

    /**
     * 设计时表单顶层的component节点样式
     */
    getClassName(): string {
        return 'farris-designer-form';
    }


    render(): string {
        const renderTemplateResult: any = this.renderTemplate('webform', {
            classes: this.getClassName(),
            children: this.renderComponents()
        });
        return super.render(renderTemplateResult);
    }

    redraw(): any {
        // Don't bother if we have not built yet.
        if (!this.element) {
            return Promise.resolve();
        }
        // 先消除已有的DOM和事件、拖拽等
        this.clear();

        this.setContent(this.element, this.render());

        // 附加拖拽等功能
        return this.attach(this.element);
    }

    /**
     * 创建控件实例
     */
    init(): any {

        this.componentId = this.form.id;
        this.viewModelId = this.form.viewModel;

        // super.init 是为了防止重复渲染增加的方法，原formio没有
        super.init();

        // remove any existing components.
        if (this.components && this.components.length) {
            this.destroyComponents();
            this.components = [];
        }

        if (this.component) {
            this.component.contents = this.form ? this.form.contents : [];
        } else {
            this.component = this.form;
        }
        this.component.type = 'form';

        this.addComponents();


        return this.formReady;
    }

    /**
     * Gets the form object.
     *
     * @returns - The form JSON schema.
     */
    get form(): any {
        if (!this._form) {
            this._form = {
                contents: []
            };
        }
        return this._form;
    }

    getComponentContents(): any[] {
        return this.form.contents;
    }


    destroy(): any {
        return super.destroy();
    }

    attach(element: HTMLElement): Promise<any> {
        this.element = element;
        this.loadRefs(element, { webform: 'single' });
        const childPromise = this.attachComponents(this.refs.webform);

        this.hook('attachWebform', element, this);
        return childPromise.then(() => {
            this.emit('render', this.element);

            return false;
        });
    }

    createUiComponent(component, options) {
        return UIComponents.create(component, options);
    }

    getAllUiTemplates() {
        return Templates.templates;
    }
}
